#include "main.h"
#include "dht11.h"
#include "delay.h"


//定义 DHT11 连接的 GPIO 端口和引脚，方便移植
#define DHT11_PORT GPIOC
#define DHT11_PIN  GPIO_PIN_10

/*
**@Brief 通过 DHT11 传感器采集一次温度和湿度数据
**
**@Params
**		temp 用于接收温度数据,如果对温度数据不感兴趣，可以传 NULL；
**		humi 用于接收湿度数据,如果对湿度数据不感兴趣，可以传 NULL；
**
**@Retval
**		采集成功返回0，否则返回非零（错误码）具体如下：
**		1 表示 DHT11 未响应(DHT11 故障或连接异常)，2 表示校验失败（可能存在干扰）
**		
**@Example
**		float t,h;
**
**		if(DHT11_Get(&t, &h) == 0)
**		{
**			//处理温湿度数据
**			// ......
**		}
*/

uint8_t data[5];
int8_t DHT11_Get(float* temp, uint8_t* humi)
{
	uint8_t i, j;
	
	
	
	GPIO_InitTypeDef conf;
	
	//将 DHT11 引脚设置为开漏输出模式
	conf.Pin = DHT11_PIN;
	conf.Mode = GPIO_MODE_OUTPUT_OD;
	conf.Pull = GPIO_NOPULL;
	conf.Speed = GPIO_SPEED_FREQ_LOW;
	
	HAL_GPIO_Init(DHT11_PORT, &conf);
	// 向 DHT11 发出开始信号
	HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN,GPIO_PIN_RESET);
	HAL_Delay(20);
	//切换到输入模式，释放总线
	conf.Mode = GPIO_MODE_INPUT;
	HAL_GPIO_Init(DHT11_PORT, &conf);
	
	// 延时 60 um
	Delay_US(60);
	
	//读取 DHT11 的响应信号
	//如果 DHT11 未响应，就返回 1，说明 DHT11 传感器故障或连接异常
	if(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET)
		return 1;
	
	//等待 DHT11 的低电平响应信号结束
	while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET);

	
	//延时 120 um
		Delay_US(120);
	
	//逐位接收温湿度数据（共 40 位， 高位先出）
	
	for(i = 0; i < 5; i++)
	{
		data[i] = 0;
		
		for(j = 0; j < 8; j++)
		{
			//等待 0 或 1 前导低电平结束
			while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET);
			
			//延时50um
			Delay_US(50);
		
			data[i] <<= 1;
				
			if(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET)
			{
				//接收到 1
				data[i] += 1;
				//延时 40 um
				Delay_US(40);
			}
			else
			{
				//接收到 0
			}
		}
		
	}
	
	//检查检验和,如果校验失败，就返回 2，说明通信存在干扰
	if(data[0] + data[1] + data[2] + data[3] != data[4])
		return 2;
	//计算温度和湿度
	if(humi != NULL) *humi = data[0];
	
	if(temp != NULL)
	{
		*temp = data[2] + (float)(data[3] & 0x7f) / 10;
		
		if(data[3] & 0x80) *temp = -*temp;
	}
	
	return 0;
}


